/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

import { hvigorCore } from '@ohos/hvigor';
import fse from 'fs-extra';
import path from 'path';

import { CommonConst } from '../../const/common-const.js';
import { InjectConst } from '../../const/inject-const.js';
import { ModuleType } from '../../enum/module-type-enum.js';
import { ModuleJson } from '../../options/configure/module-json-options.js';
import { FileUtil } from '../../utils/file-util.js';
import { OhosLogger } from '../../utils/log/ohos-logger.js';
import { TaskNames } from '../common/task-names.js';
import { PreviewHookCompileResource } from '../hook/preview-hook-compile-resource.js';
import { TargetTaskService } from '../service/target-task-service.js';
import { OhosHapTask } from '../task/ohos-hap-task.js';
import CommonTask = TaskNames.CommonTask;
import { getJson5Obj } from '../../utils/json-util.js';

import { CopyPreviewProfile } from './copy-preview-profile.js';

/**
 * accept previewer args then replace into page file
 */
export class ReplacePreviewerPage extends OhosHapTask {
  private _log: OhosLogger = OhosLogger.getLogger(ReplacePreviewerPage.name);

  constructor(taskService: TargetTaskService) {
    super(taskService, CommonTask.REPLACE_PREVIEWER_PAGES);
  }

  initTaskDepends(): void {
    this.declareDepends(PreviewHookCompileResource.name);

    // 1.处理资源增量编译时，restool不复制resouces目录，手动copy profile路由配置文件
    const compileResInc = hvigorCore.getExtraConfig().get(InjectConst.PREVIEWER_COMPILE_RES_INC);
    if (compileResInc === 'true') {
      this.declareDepends(CopyPreviewProfile.name);
    }
  }

  protected doTaskAction() {
    this.processPreviewProfile(this._log);
  }

  /**
   * Preview stage模型资源编译之后处理profile路由配置
   *
   * @param {OhosLogger} log
   * @private
   */
  protected processPreviewProfile(log: OhosLogger): void {
    // 1.在资源中间产物module.json文件中添加main_pages.json文件引用
    this.appendMainPages();

    // 2.处理非路由预览
    let shouldReplacePreviewPage = true;
    const compileHspDependencies = hvigorCore.getExtraConfig().get('compileHspDependencies');
    if (compileHspDependencies) {
      // entry依赖hsp(s)预览entry时，由于现在entry和hsp在一条预览命令里编译，但hsp却不需要replacePreviewPage。所以这里要把依赖的hsp排除掉.
      const mainModule = hvigorCore.getExtraConfig().get('mainModule');
      const module = this.targetData.getModuleModel(); // 本次预览的主模块
      if (module.getName() !== mainModule && module.getModuleType() === ModuleType.Shared) {
        // 依赖的hsp不应该替换previewPage
        shouldReplacePreviewPage = false;
      }
    }

    if (shouldReplacePreviewPage) {
      this.replacePreviewPage(log);
    }
  }

  /**
   * Preview 处理非路由预览，替换profile路由文件内容
   * @param {OhosLogger} log
   * @return {boolean} true 表示处理完成， false 未处理
   * @private
   */
  private replacePreviewPage(log: OhosLogger): boolean {
    const previewPage: string | undefined = hvigorCore.getExtraConfig().get(InjectConst.PREVIEWER_REPLACE_PAGE);
    if (previewPage) {
      this.replacePagesInPreview(log, [previewPage]);
      return true;
    }
    return false;
  }

  /**
   * 在资源中间产物module.json文件中添加main_pages.json文件引用 保证hsp模块module.json中始终存在main_pages.json文件引用
   * @private
   */
  private appendMainPages(): void {
    if (this.moduleModel.getModuleType() !== ModuleType.Shared) {
      return;
    }
    const moduleJsonPath: string = path.resolve(this.pathInfo.getIntermediatesRes(), CommonConst.MODULE_JSON);
    const moduleJsonObj: ModuleJson.ModuleOptObj = getJson5Obj(moduleJsonPath);
    Object.assign(moduleJsonObj.module, { pages: '$profile:main_pages' });
    const intermediatesResModuleJsonPath = this.pathInfo.getPreviewIntermediatesResModuleJsonPath();
    FileUtil.checkFile(intermediatesResModuleJsonPath);
    fse.writeJSONSync(intermediatesResModuleJsonPath, moduleJsonObj);
  }
}
